package shogi;

import shogi.pieces.Piece;

public class ShogiControllerProduct {

    private int[] leftPlacement;
    private boolean legalBishop;

    public int[] getLeftPlacement() {
        return leftPlacement;
    }

    public void setLeftPlacement(int[] leftPlacement) {
        this.leftPlacement = leftPlacement.clone();
    }

    public boolean getLegalBishop() {
        return legalBishop;
    }

    public void setLegalBishop(boolean legalBishop) {
        this.legalBishop = legalBishop;
    }

    public int getLeftPlacement(int i) {
        return leftPlacement[i];
    }

    public void setLeftPlacement(int i, int value) {
        this.leftPlacement[i] = value;
    }

    public boolean isLegal(int originalIndex, int destinationIndex,
            Piece aShogiPiece, ShogiController shogiController) {
        int originalRow = originalIndex / 9;
        int originalColumn = originalIndex % 9;
        int destinationRow = destinationIndex / 9;
        int destinationColumn = destinationIndex % 9;
        switch (aShogiPiece.getType()) {
            case 'n':
                caseN(aShogiPiece, originalRow, originalColumn, destinationRow,
                        destinationColumn);
            case 'g':
                Boolean res = caseG(aShogiPiece, originalRow, originalColumn,
                        destinationRow, destinationColumn);
                if (res != null) {
                    return res;
                }
            case 's':
                return caseS(originalIndex, destinationIndex, aShogiPiece,
                        originalRow, originalColumn, destinationRow,
                        destinationColumn);
            case 'b':
                return caseB(shogiController, originalRow, originalColumn,
                        destinationRow, destinationColumn);
            case 'r':
                res = caseR(originalIndex, destinationIndex, shogiController,
                        originalRow, originalColumn, destinationRow,
                        destinationColumn);
                if (res != null) {
                    return res;
                }
            case 'p':
                return caseP(originalIndex, destinationIndex, aShogiPiece);
            case 'k':
                return caseK(originalRow, originalColumn, destinationRow,
                        destinationColumn);
            case 'l':
                res = caseL(originalIndex, destinationIndex, aShogiPiece,
                        shogiController, originalRow, originalColumn,
                        destinationRow, destinationColumn);
                if (res != null) {
                    return res;
                }
            default:
                return false;
        }
    }

    private Boolean caseL(int originalIndex, int destinationIndex,
            Piece aShogiPiece, ShogiController shogiController,
            int originalRow, int originalColumn, int destinationRow,
            int destinationColumn) {
        if (originalRow == destinationRow) {
            if (aShogiPiece.getOrientation().equalsIgnoreCase("left")
                    && originalColumn < destinationColumn) {
                for (int i = originalIndex + 1; i < destinationIndex; i++) {
                    if (shogiController.getRightPlacement(i) == 1
                            || getLeftPlacement(i) == 1) {
                        return false;
                    }
                }
                return true;
            }
            if (aShogiPiece.getOrientation().equalsIgnoreCase("right")
                    && originalColumn > destinationColumn) {
                for (int i = originalIndex - 1; i > destinationIndex; i--) {
                    if (shogiController.getRightPlacement(i) == 1
                            || getLeftPlacement(i) == 1) {
                        return false;
                    }
                }
                return true;
            }
        } else {
            return false;
        }
        return null;
    }

    private Boolean caseR(int originalIndex, int destinationIndex,
            ShogiController shogiController, int originalRow,
            int originalColumn, int destinationRow, int destinationColumn) {
        if (originalRow == destinationRow) {
            if (destinationIndex > originalIndex) {
                for (int i = originalIndex + 1; i < destinationIndex; i++) {
                    if (shogiController.getRightPlacement(i) == 1
                            || getLeftPlacement(i) == 1) {
                        return false;
                    }
                }
                return true;
            }
            if (destinationIndex < originalIndex) {
                for (int i = originalIndex - 1; i > destinationIndex; i--) {
                    if (shogiController.getRightPlacement(i) == 1
                            || getLeftPlacement(i) == 1) {
                        return false;
                    }
                }
                return true;
            }
        } else if (destinationColumn == originalColumn) {
            if (destinationIndex > originalIndex) {
                for (int i = originalIndex + 9; i < destinationIndex; i += 9) {
                    if (shogiController.getRightPlacement(i) == 1
                            || getLeftPlacement(i) == 1) {
                        return false;
                    }
                }
                return true;
            } else if (destinationIndex < originalIndex) {
                for (int i = originalIndex - 9; i > destinationIndex; i -= 9) {
                    if (shogiController.getRightPlacement(i) == 1
                            || getLeftPlacement(i) == 1) {
                        return false;
                    }
                }
                return true;
            }
        } else {
            return false;
        }
        return null;
    }

    private Boolean caseG(Piece aShogiPiece, int originalRow,
            int originalColumn, int destinationRow, int destinationColumn) {
        if (originalRow == destinationRow) {
            if (destinationColumn == (originalColumn + 1)
                    || destinationColumn == (originalColumn - 1)) {
                return true;
            }
        } else if (originalColumn == destinationColumn) {
            if (destinationRow == (originalRow + 1)
                    || destinationRow == (originalRow - 1)) {
                return true;
            }
        } else if (aShogiPiece.getOrientation().equalsIgnoreCase("left")) {
            if ((destinationColumn == (originalColumn + 1))
                    && (destinationRow == (originalRow - 1) || destinationRow == (originalRow + 1))) {
                return true;
            }
        } else if (aShogiPiece.getOrientation().equalsIgnoreCase("right")) {
            if ((destinationColumn == (originalColumn - 1))
                    && (destinationRow == (originalRow - 1) || destinationRow == (originalRow + 1))) {
                return true;
            }
        } else {
            return false;
        }
        return null;
    }

    private boolean caseK(int originalRow, int originalColumn,
            int destinationRow, int destinationColumn) {
        if (Math.abs(originalRow - destinationRow) < 2
                && Math.abs(originalColumn - destinationColumn) < 2) {
            return true;
        } else {
            return false;
        }
    }

    private boolean caseP(int originalIndex, int destinationIndex,
            Piece aShogiPiece) {
        if ((aShogiPiece.getOrientation().equalsIgnoreCase("left") && destinationIndex == (originalIndex + 1))
                || (aShogiPiece.getOrientation().equalsIgnoreCase("right") && destinationIndex == (originalIndex - 1))) {
            return true;
        } else {
            return false;
        }
    }

    private boolean caseB(ShogiController shogiController, int originalRow,
            int originalColumn, int destinationRow, int destinationColumn) {
        legalBishop = false;
        if (Math.abs(originalRow - destinationRow) == Math.abs(originalColumn
                - destinationColumn)) {
            legalBishop = true;
            if (destinationRow < originalRow
                    && destinationColumn < originalColumn) {
                for (int delta = 1; (delta <= Math.abs(originalRow
                        - destinationRow) && delta <= Math.abs(originalColumn
                        - destinationColumn)); delta++) {
                    if (shogiController.getRightPlacement(9
                            * (originalRow - delta) + originalColumn - delta) == 1
                            || getLeftPlacement(9 * (originalRow - delta)
                            + originalColumn - delta) == 1) {
                        if (originalRow - delta == destinationRow) {
                            legalBishop = true;
                        } else {
                            legalBishop = false;
                        }
                        break;
                    }
                }
            } else if (destinationRow > originalRow
                    && destinationColumn > originalColumn) {
                for (int delta = 1; (delta <= Math.abs(originalRow
                        - destinationRow) && delta <= Math.abs(originalColumn
                        - destinationColumn)); delta++) {
                    if (shogiController.getRightPlacement(9
                            * (originalRow + delta) + originalColumn + delta) == 1
                            || getLeftPlacement(9 * (originalRow + delta)
                            + originalColumn + delta) == 1) {
                        if (originalRow + delta == destinationRow) {
                            legalBishop = true;
                        } else {
                            legalBishop = false;
                        }
                        break;
                    }
                }
            } else if (destinationRow < originalRow
                    && destinationColumn > originalColumn) {
                for (int delta = 1; (delta <= Math.abs(originalRow
                        - destinationRow) && delta <= Math.abs(originalColumn
                        - destinationColumn)); delta++) {
                    if (shogiController.getRightPlacement(9
                            * (originalRow - delta) + originalColumn + delta) == 1
                            || getLeftPlacement(9 * (originalRow - delta)
                            + originalColumn + delta) == 1) {
                        if (originalRow - delta == destinationRow) {
                            legalBishop = true;
                        } else {
                            legalBishop = false;
                        }
                        break;
                    }
                }
            } else if (destinationRow > originalRow
                    && destinationColumn < originalColumn) {
                for (int delta = 1; (delta <= Math.abs(originalRow
                        - destinationRow) && delta <= Math.abs(originalColumn
                        - destinationColumn)); delta++) {
                    if (shogiController.getRightPlacement(9
                            * (originalRow + delta) + originalColumn - delta) == 1
                            || getLeftPlacement(9 * (originalRow + delta)
                            + originalColumn - delta) == 1) {
                        if (originalRow + delta == destinationRow) {
                            legalBishop = true;
                        } else {
                            legalBishop = false;
                        }
                        break;
                    }
                }
            }
            return legalBishop;
        } else {
            return false;
        }
    }

    private boolean caseS(int originalIndex, int destinationIndex,
            Piece aShogiPiece, int originalRow, int originalColumn,
            int destinationRow, int destinationColumn) {
        if ((destinationRow == originalRow + 1 || destinationRow == originalRow - 1)
                && (destinationColumn == originalColumn + 1 || destinationColumn == originalColumn - 1)) {
            return true;
        } else {
            return caseP(originalIndex, destinationIndex, aShogiPiece);
        }
    }

    private void caseN(Piece aShogiPiece, int originalRow, int originalColumn,
            int destinationRow, int destinationColumn) {
        aShogiPiece.isMoveLegal(originalRow, originalColumn, destinationRow,
                destinationColumn);
    }
}